/*
* 矩阵变换
* 平移不是线性变换，因为线性变换需保持原点不变，而平移需要移动原点。所以3x3和2x2矩阵只能表示线性变换，如旋转、缩放、反射、错切。平移需要仿射变换，因此必须使用4x4矩阵和齐次坐标。
*/

// 沿着X轴缩放
mat3 scaleX(float x){
    return mat3(
        x,0.,0.,
        0.,1.,0.,
        0.,0.,1.
    );
}
// 沿着Y轴缩放
mat3 scaleY(float y){
    return mat3(
        1.,0.,0.,
        0.,y,0.,
        0.,0.,1.
    );
}
// 沿着Z轴缩放
mat3 scaleZ(float z){
    return mat3(
        1.,0.,0.,
        0.,1.,0.,
        0.,0.,z
    );
}
// 沿着任意轴缩放
mat3 scale(vec3 axis){
    float x=axis.x,y=axis.y,z=axis.z;
    return mat3(
        x,0.,0.,
        0.,y,0.,
        0.,0.,z
    );
}
// 绕X轴旋转
mat3 rotateX(float angle){
    float radian=radians(angle);
    float s=sin(radian),c=cos(radian);
    // 按列填充
    return mat3(
        1.,0.,0.,// 第一列
        0.,c,-s,// 第二列
        0.,s,c// 第三列
    );
}
// 绕Y轴旋转
mat3 rotateY(float angle){
    float radian=radians(angle);
    float s=sin(radian),c=cos(radian);
    // 按列填充
    return mat3(
        c,0.,s,// 第一列
        0.,1.,0.,// 第二列
        -s,0.,c// 第三列
    );
}
// 绕Z轴旋转
mat3 rotateZ(float angle){
    float radian=radians(angle);
    float s=sin(radian),c=cos(radian);
    // 按列填充
    return mat3(
        c,s,0.,// 第一列
        -s,c,0.,// 第二列
        0.,0.,1.// 第三列
    );
}
// 绕任意轴旋转
mat3 rotate(vec3 axis,float angle){
    float x=axis.x,y=axis.y,z=axis.z;
    float radian=radians(angle);
    float s=sin(radian),c=cos(radian);
    float t=1.-c;
    float m0=x*x*t+c,
    m1=x*y*t-z*s,
    m2=x*z*t+y*s,
    m3=y*x*t+z*s,
    m4=y*y*t+c,
    m5=y*z*t-x*s,
    m6=z*x*t-y*s,
    m7=z*y*t+x*s,
    m8=z*z*t+c;
    
    // 按列填充
    return mat3(
        m0,m1,m2,// 第一列
        m3,m4,m5,// 第二列
        m6,m7,m8// 第三列
    );
}

// 沿着X轴镜像
mat3 mirrorX(){
    return mat3(
        -1.,0.,0.,
        0.,1.,0.,
        0.,0.,1.
    );
}
// 沿着Y轴镜像
mat3 mirrorY(){
    return mat3(
        1.,0.,0.,
        0.,-1.,0.,
        0.,0.,1.
    );
}
// 沿着Z轴镜像
mat3 mirrorZ(){
    return mat3(
        1.,0.,0.,
        0.,1.,0.,
        0.,0.,-1.
    );
}
// 指定轴镜像
mat3 mirror(vec3 axis){
    axis=normalize(axis);
    float x=axis.x,y=axis.y,z=axis.z;
    return mat3(
        1.-2.*x*x,-2.*x*y,-2.*x*z,
        -2.*x*y,1.-2.*y*y,-2.*z*y,
        -2.*x*z,-2.*y*z,1.-2.*z*z
    );
}
// 沿着X轴错切
mat3 shearX(vec2 axis){
    float xy=axis.x,xz=axis.y;
    return mat3(
        1.,0.,0.,
        xy,1.,0.,
        xz,0.,1.
    );
}
// 沿着Y轴错切
mat3 shearY(vec2 axis){
    float yx=axis.x,yz=axis.y;
    return mat3(
        1.,yx,0.,
        0.,1.,0.,
        0.,yz,1.
    );
}
// 沿着Z轴错切
mat3 shearZ(vec2 axis){
    float zx=axis.x,zy=axis.y;
    return mat3(
        1.,0.,zx,
        0.,1.,zy,
        0.,0.,1.
    );
}
// 指定轴错切
mat3 shear(vec2 axisX,vec2 axisY,vec2 axisZ){
    float xy=axisX.x,xz=axisX.y;
    float yx=axisY.x,yz=axisY.y;
    float zx=axisZ.x,zy=axisZ.y;
    return mat3(
        1.,yx,zx,
        xy,1.,zy,
        xz,yz,1.
    );
}